package com.sam.core;

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import net.sf.ezmorph.object.DateMorpher;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import net.sf.json.JsonConfig;
import net.sf.json.util.JSONUtils;
import net.sf.json.util.PropertyFilter;

import org.apache.commons.mail.EmailException;
import org.apache.commons.mail.SimpleEmail;
import org.apache.struts2.ServletActionContext;
import org.apache.struts2.config.ParentPackage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.sam.core.domain.Page;
import com.sam.core.util.json.DateJsonValueProcessor;
import com.sam.security.domain.Mail;
import com.sam.security.domain.User;

/**
 * Struts2基类
 * @project EMan
 * @author Sam
 * @version
 * @date Feb 10, 2009 10:23:48 AM
 */
@SuppressWarnings("unchecked")
@ParentPackage("default")
public class BaseAction extends ActionSupport {

	private static final long serialVersionUID = 1L;

	public static final String JSON_ERROR = "{error:true}";
	public static final String JSON_SUCCESS = "{success:true}";
	public static final String JSON = "json";

	/**
	 * 获取 application 对象.
	 * @return the application
	 */
	public static ServletContext getApplication() {
		return ServletActionContext.getServletContext();
	}

	/**
	 * 获取request对象.
	 * @return the request
	 */
	public static HttpServletRequest getRequest() {
		return ServletActionContext.getRequest();
	}

	/**
	 * 获取response对象.
	 * @return the response
	 */
	public static HttpServletResponse getResponse() {
		return ServletActionContext.getResponse();
	}

	/**
	 * 获取session对象.
	 * @return the session
	 */
	public static HttpSession getSession() {
		return (ServletActionContext.getRequest()).getSession();
	}

	/**
	 * 获取请求对象.
	 * @param create the create
	 * @return the session
	 */
	public static HttpSession getSession(boolean create) {
		return (ServletActionContext.getRequest()).getSession(create);
	}

	/**
	 * 读取 session 中的属性值.
	 * @param name the name
	 * @return the session
	 */
	public static Object getSession(String name) {
		ActionContext ctx = ActionContext.getContext();
		Map session = ctx.getSession();

		return session.get(name);
	}

	/**
	 * 向 session 设置属性值.
	 * @param name the name
	 * @param value the value
	 */
	public static void setSession(Object name, Object value) {
		ActionContext ctx = ActionContext.getContext();
		Map session = ctx.getSession();
		session.put(name, value);
	}

	// 返回的json字符串
	protected String jsonString;
	// 模糊查询的字符串
	protected String query;
	// 请求参数
	protected String dataString;
	// 分页参数,起始记录
	protected int start = 0;
	// 分页参数,返回的最大记录条数
	protected int limit = Constants.SYSTEM_CONFIG_PAGESIZE;
	// 分页参数,排序字段
	protected String sort = Page.DEFAULT_ORDER_BY;
	// 分页参数,排序类型
	protected String dir = Page.DEFAULT_ORDER;

	// 日志
	protected static Logger log = LoggerFactory.getLogger(BaseAction.class);

	/**
	 * 获取属性值
	 * @param name
	 * @return
	 */
	public Object getAttribute(String name) {
		return ServletActionContext.getRequest().getAttribute(name);
	}

	public String getDataString() {
		return dataString;
	}

	/**
	 * get jsonString
	 * @return
	 */
	public String getJsonString() {
		return jsonString;
	}

	public int getLimit() {
		return limit;
	}

	/**
	 * 读取表单参数.
	 * @param name the name
	 * @return the parameter
	 */
	public String getParameter(String name) {
		return ServletActionContext.getRequest().getParameter(name);
	}

	/**
	 * 将表单参数作为布尔值返回.
	 * @param name 表单参数名
	 * @return the parameter boolean
	 */
	public boolean getParameterBoolean(String name) {
		String s = getParameter(name);

		if (s == null) {
			return false;
		} else {
			try {
				return Boolean.parseBoolean(s);
			} catch (NumberFormatException e) {
				e.printStackTrace();
			}
		}

		return false;
	}

	/**
	 * 将表单参数作为整数返回.
	 * @param name 表单参数名
	 * @return the parameter int
	 */
	public int getParameterInt(String name) {
		String s = getParameter(name);

		if (s == null) {
			return 0;
		} else {
			try {
				return Integer.parseInt(s);
			} catch (NumberFormatException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

		return 0;
	}

	/**
	 * 将表单参数作为长整数返回.
	 * @param name 表单参数名
	 * @return the parameter long
	 */
	public long getParameterLong(String name) {
		String s = getParameter(name);

		if (s == null) {
			return 0L;
		} else {
			try {
				return Long.parseLong(s);
			} catch (NumberFormatException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

		return 0L;
	}

	public String getQuery() {
		return query;
	}

	/**
	 * 获取当前会话的登录用户信息.
	 * @return User
	 */
	public User getLoginUser() {
		User currentUser = (User) getSession(Constants.USER_IN_SESSION);
		return currentUser;
	}

	public int getStart() {
		return start;
	}

	/**
	 * 将所有URL参数合并成一个URL字符串(page参数除外), 提供分页时显示.
	 * @return 字符串, 如: para1=11&para2=bb
	 */
	public String mergeParamsAsURI() {
		Map<String, String[]> params = getRequest().getParameterMap();

		StringBuffer out = new StringBuffer();

		Set<String> keys = params.keySet();// 列出所有表单参数

		for (String key : keys) {
			if (!"page".equals(key)) {
				// TODO 发现Map值有乱码 --> 
				String[] values = params.get(key);// 尝试获取多个参数

				// 不管单个参数还是多个参数统一转成了数组
				if (values.length > 1) {
					values = getRequest().getParameterValues(key);
				} else {
					values = new String[] { getParameter(key) };
				}

				log.debug("key=" + key);

				try {
					for (String value : values) {
						log.debug("value=" + value);
						out.append(java.net.URLEncoder.encode(key, "UTF-8") + "=");
						out.append(java.net.URLEncoder.encode(value, "UTF-8") + "&");
						// key=value&
					}

				} catch (UnsupportedEncodingException e) {
					e.printStackTrace();
				}
			}
		}

		// 删除末尾多余的 & 字符
		if (out.toString().endsWith("&")) {
			out.deleteCharAt(out.length() - 1);
		}

		return out.toString();
	}

	/**
	 * 从json字符串中解析Java对象
	 * @param dataString
	 * @param clz
	 * @return
	 */
	public List<Object> parseObject(String dataString, Class clz) {
		// 注册日期格式化对象
		String[] dateFormats = new String[] { "yyyy-MM-dd", "yyyy-MM-dd HH:mm",
				"yyyy-MM-dd HH:mm:ss" };
		JSONUtils.getMorpherRegistry().registerMorpher(new DateMorpher(dateFormats));
		// 过滤空对象
		JsonConfig jsonConfig = new JsonConfig();
		jsonConfig.setRootClass(clz);
		jsonConfig.setJavaPropertyFilter(new PropertyFilter() {
			public boolean apply(Object source, String name, Object value) {
				if (value == null || "".equals(value)) {
					return true;
				}
				return false;
			}
		});
		List<Object> list = new ArrayList<Object>();
		JSONArray jsonArr = JSONArray.fromObject(dataString);
		for (int i = 0; i < jsonArr.size(); i++) {
			JSONObject jsonObj = jsonArr.getJSONObject(i);
			try {
				Object obj = JSONObject.toBean(jsonObj, jsonConfig);
				list.add(obj);
			} catch (RuntimeException e) {
				e.printStackTrace();
			}
		}
		return list;
	}

	/**
	 * 返回执行是否成功的json字符串
	 * @param success
	 */
	public void sendJSON(boolean success) {
		jsonString = "{success:" + success + "}";
	}

	/**
	 * 返回执行是否成功的json字符串
	 * @param success
	 */
	public void sendJSON(boolean success, String msg) {
		jsonString = "{success:" + success + ",msg:'" + msg + "'}";
	}

	/**
	 * 返回json字符串
	 * @param total 记录总条数
	 * @param obj array对象
	 */
	public void sendJSON(long total, Object obj) {
		DateJsonValueProcessor beanProcessor = new DateJsonValueProcessor();
		JsonConfig config = new JsonConfig();
		config.registerJsonValueProcessor(java.util.Date.class, beanProcessor);
		JSONArray jsonArray = JSONArray.fromObject(obj, config);
		try {
			jsonString = "{\"success\":" + true + ",\"total\":" + total + ",\"root\":"
					+ jsonArray.toString() + "}";
		} catch (Exception e) {
			log.error("转换对象为jsonString失败", e);
			jsonString = "{success:false}";
		}
	}

	/**
	 * 直接返回对象的json字符串
	 * @param obj
	 */
	public void sendJSON(Object obj) {
		DateJsonValueProcessor beanProcessor = new DateJsonValueProcessor();
		JsonConfig config = new JsonConfig();
		config.registerJsonValueProcessor(java.util.Date.class, beanProcessor);
		JSONArray jsonArray = JSONArray.fromObject(obj, config);
		try {
			jsonString = jsonArray.toString();
		} catch (Exception e) {
			log.error("转换对象为jsonString失败", e);
			jsonString = "{success:false}";
		}
	}

	/**
	 * 返回对象的json字符串,过滤对象的属性
	 * @param obj
	 * @param config 配置需要过滤的属性
	 */
	public void sendJSON(Object obj, JsonConfig config) {
		DateJsonValueProcessor beanProcessor = new DateJsonValueProcessor();
		config.registerJsonValueProcessor(java.util.Date.class, beanProcessor);
		JSONArray jsonObject = JSONArray.fromObject(obj, config);
		try {
			jsonString = jsonObject.toString();
		} catch (Exception e) {
			log.error("转换对象为jsonString失败", e);
			jsonString = "{success:false}";
		}
	}

	/**
	 * 发送e-mail
	 * @param mail
	 */
	public void sendMail(Mail mail) {
		try {
			SimpleEmail email = new SimpleEmail();
			// 设置发送主机的服务器地址
			email.setHostName("smtp.163.com");
			// 设置收件人邮箱
			email.addTo("anming81@163.com", "sam");
			// 发件人邮箱
			email.setFrom("anming81@163.com", "sam");
			// 如果要求身份验证，设置用户名、密码，分别为发件人在邮件服务器上注册的用户名和密码
			email.setAuthentication("anming81", "7225927");
			// 设置邮件的主题
			email.setSubject("Hello, This is My First Email Application");
			// 邮件正文消息
			email.setMsg("I am bulktree This is JavaMail Application");
			email.send();
		} catch (EmailException e) {
			e.printStackTrace();
		}
		System.out.println("The SimpleEmail send sucessful!!!");
	}

	/**
	 * 设置 request 的属性.
	 * @param name 属性名
	 * @param value 属性值
	 */
	public void setAttribute(String name, Object value) {
		ServletActionContext.getRequest().setAttribute(name, value);
	}

	public void setDataString(String dataString) {
		this.dataString = dataString;
	}

	public void setJsonString(String jsonString) {
		this.jsonString = jsonString;
	}

	public void setLimit(int limit) {
		this.limit = limit;
	}

	public void setQuery(String query) {
		this.query = query;
	}

	public void setStart(int start) {
		this.start = start;
	}

	public String getSort() {
		return sort;
	}

	public void setSort(String sort) {
		this.sort = sort;
	}

	public String getDir() {
		return dir;
	}

	public void setDir(String dir) {
		this.dir = dir;
	}
}
